﻿using System.Reflection;
using System.Xml;
Console.WriteLine("SCAWARADA v.1.0 start...");
string[] cmdargs = Environment.GetCommandLineArgs();

string sarg = "";
foreach (var arg in cmdargs)
{
    Console.WriteLine(arg);
    if (sarg == "-p")
    {
        Starter.ProjectPath = arg;
    }
    sarg = arg;
}
try
{
    Starter Starter = new Starter(1);
}
catch (Exception ex) { Console.WriteLine(ex.ToString()); }
class Starter
{
    
    Thread myThread;

    string exectag = "";
    string compltag = "";
    string errtag = "";
   

    string param;
    string paramtag1;
    string paramtag2;
    string paramtag3;
    string paramtag4;
    string func = "";

    DataCollector.Buffer TagBuffer = new DataCollector.Buffer();
    DataStorage.Storage Storage = new DataStorage.Storage();

    WebPublisher.Publisher WPublisher = new WebPublisher.Publisher();

    TelegramBot.bot TLGbot = new TelegramBot.bot();

    EMailClient.Client eMailClient = new EMailClient.Client();
    SMSSender.SMS SMS = new SMSSender.SMS();

    TaskTimer.Timer tmr = new TaskTimer.Timer();
    TaskClock.Clock clock = new TaskClock.Clock();

    TaskScript.Script scrpt = new TaskScript.Script();

    TaskAlarm.Alarm alarm = new TaskAlarm.Alarm();
    TaskTrend.Trend trend = new TaskTrend.Trend();

    //Подтягиваем dll драйвера

    static string iodllpath;// внешняя библиотека
    static Assembly assmbl;

    Object oio;// объект для внешней библиотеки
    Type tio;// класс внешней библиотеки

    XmlDocument taskFile;
   public static string ProjectPath = @"C:\prog\scawarada22\PROJECT\"; //@"C:\prog\scawarada22\PROJECT\";
    public Starter(int i)
    {


        int err;

        myThread = new Thread(Buffer);
        myThread.Name = $"Buffer";
        myThread.Start();
        TagBuffer.SetTag(out err, "System_Date", 0, "string");
        TagBuffer.SetTag(out err, "System_Day", 0, "int");
        TagBuffer.SetTag(out err, "System_Month", 0, "int");
        TagBuffer.SetTag(out err, "System_Year", 0, "int");
        TagBuffer.SetTag(out err, "System_Time", 0, "string");
        TagBuffer.SetTag(out err, "System_Hour", 0, "int");
        TagBuffer.SetTag(out err, "System_Minute", 0, "int");
        TagBuffer.SetTag(out err, "System_Second", 0, "int");
        foreach (string line in System.IO.File.ReadLines(ProjectPath + "tagl.txt"))
        {
            string[] parts = line.Split(Convert.ToChar(9)); ;
            int sz = Convert.ToInt32(parts[2]);
            int ret = Convert.ToInt32(parts[3]);
            object val = parts[4];
            TagBuffer.SetTag(out err, parts[0], val, parts[1], 0, sz, ret);
        }
       
        string hstpath;
        TagBuffer.SetTag(out err, "System_Startup", 0, "int");
        taskFile = new XmlDocument();     
        taskFile.Load(ProjectPath + "tasks.xml");
        string filename = "";
        XmlElement? txmlRoot = taskFile.DocumentElement;
        if (txmlRoot != null)
        {
            XmlNode sNode;
            string bgtaskname;
            
            XmlNodeList? taskNodes = txmlRoot?.SelectNodes("bgtask");

            foreach (XmlNode taskNode in taskNodes)
            {
                sNode = taskNode.SelectSingleNode("name");
                bgtaskname = sNode.InnerText;
                if (taskNode.SelectSingleNode("enabled").InnerText == "1")
                {
                    errtag = taskNode.SelectSingleNode("errortag").InnerText;

                    if (bgtaskname == "storage")
                    {
                        XmlNode xmlNode;
                        xmlNode = taskNode.SelectSingleNode("database");
                        if (xmlNode != null) { param = xmlNode.InnerText; } else { param = "0"; }
                        xmlNode = taskNode.SelectSingleNode("connectionstring");
                        string constr = "";
                        if (xmlNode != null) constr = xmlNode.InnerText;
                        if (constr != "") { param = param + '\t' + constr; }
                        else { param = param + '\t' + ProjectPath + "hst/"; }
                        xmlNode = taskNode.SelectSingleNode("storagedays");
                        string storedays = "0";
                        if (xmlNode != null) storedays = xmlNode.InnerText;
                        param = param + '\t' + storedays;
                       
                        myThread = new Thread(DStorage);
                        myThread.Name = $"Storage";
                        myThread.Start();
                    }
                    if (bgtaskname == "webserver")
                    {
                        param = ProjectPath + "www/," + taskNode.SelectSingleNode("port").InnerText;
                        myThread = new Thread(WebServer);
                        myThread.Name = $"WebServer";
                        myThread.Start();
                    }
                    if (bgtaskname == "telegrambot")
                    {
                        param = taskNode.SelectSingleNode("botid").InnerText;
                        paramtag1 = taskNode.SelectSingleNode("querytag").InnerText;
                        paramtag2 = taskNode.SelectSingleNode("msgtag").InnerText;
                        paramtag3 = taskNode.SelectSingleNode("querychattag").InnerText;
                        paramtag4 = taskNode.SelectSingleNode("resettag").InnerText;
                        filename = ProjectPath + "telegramscript.js";
                        if (File.Exists(filename))
                        {
                            func = File.ReadAllText(filename);
                        }
                        myThread = new Thread(Telegram);
                        myThread.Name = $"TelegramBot";
                        myThread.Start();
                    }
                    if (bgtaskname == "mailclient")
                    {
                        param = taskNode.SelectSingleNode("server").InnerText + '\t' + taskNode.SelectSingleNode("port").InnerText + '\t' +
                            taskNode.SelectSingleNode("authen").InnerText + '\t' + taskNode.SelectSingleNode("username").InnerText + '\t' + 
                            taskNode.SelectSingleNode("password").InnerText + '\t' +
                            taskNode.SelectSingleNode("sslen").InnerText + '\t' + taskNode.SelectSingleNode("from").InnerText + '\t' +
                            taskNode.SelectSingleNode("timeout").InnerText + '\t' + taskNode.SelectSingleNode("resettag").InnerText;
                        myThread = new Thread(MailClient);

                        myThread.Name = $"MailClient";
                        myThread.Start();
                    }
                    if (bgtaskname == "sms")
                    {
                        param = taskNode.SelectSingleNode("port").InnerText;
                        paramtag4 = taskNode.SelectSingleNode("resettag").InnerText;
                        myThread = new Thread(SMSClient);
                        myThread.Name = $"SMS";
                        myThread.Start();
                    }
                    Thread.Sleep(50);
                }
            }
            sNode = txmlRoot?.SelectSingleNode("startup");
            if (sNode != null)
            {
                TagBuffer.AddTagAction(out err, sNode.InnerText, "System_Startup");
            }
            

            taskNodes = txmlRoot?.SelectNodes("task");
            string taskname = "";
            
            foreach (XmlNode taskNode in taskNodes)
            {
                sNode = taskNode.SelectSingleNode("name");
                if (sNode != null)
                {
                    taskname = sNode.InnerText;
                    if (taskname.Contains('$'))
                    {
                        compltag = taskname.Replace("$","");
                    }
                    else
                    {
                        compltag = "System_" + taskname + "_Compl";
                        exectag = "System_" + taskname + "_Exec";
                        errtag = "System_" + taskname + "_Error";
                        TagBuffer.SetTag(out err, exectag, 0, "int");
                        TagBuffer.SetTag(out err, compltag, 0, "int");
                        TagBuffer.SetTag(out err, errtag, 0, "int");
                    }
                }
                sNode = taskNode.SelectSingleNode("next");
                if (sNode != null)
                {
                    string[] nextacts = sNode.InnerText.Split('+');
                    string action = "";
                    foreach(string nextact in nextacts)
                    {
                        if (action != "") action += "+";
                        if (nextact!="") action += "System_" + nextact + "_Exec";
                    }
                    if (action != "")  TagBuffer.AddTagAction(out err, action, compltag);
                }
                else
                {
                    sNode = taskNode.SelectSingleNode("nextcondition");
                    if (sNode != null)
                    {
                        TagBuffer.AddTagAction(out err, sNode.InnerText, compltag);
                    }
                }
            }
            foreach (XmlNode taskNode in taskNodes)
            {
                sNode = taskNode.SelectSingleNode("name");
                if (sNode != null && !sNode.InnerText.Contains('$'))
                {
                    taskname = sNode.InnerText;
                    compltag = "System_" + taskname + "_Compl";
                    exectag = "System_" + taskname + "_Exec";
                    errtag = "System_" + taskname + "_Error";

                    sNode = taskNode.SelectSingleNode("type");
                    if (sNode != null)
                    {
                        if (sNode.InnerText != "script")
                        {
                            filename = ProjectPath + "tasks/" + taskname + ".xml";
                            taskFile = new XmlDocument();
                            Console.WriteLine(filename);
                            taskFile.Load(filename);
                        }
                        if (sNode.InnerText == "timer")
                        {
                            myThread = new Thread(Timer1);
                            myThread.IsBackground = true;
                            myThread.Name = taskname;
                            myThread.Start();
                            Thread.Sleep(100);
                        }
                        if (sNode.InnerText == "clock")
                        {
                            myThread = new Thread(Clock1);
                            myThread.IsBackground = true;
                            myThread.Name = taskname;
                            myThread.Start();
                            Thread.Sleep(100);
                        }
                        if (sNode.InnerText == "alarm")
                        {
                            myThread = new Thread(Alarm1);
                            myThread.IsBackground = true;
                            myThread.Name = taskname;
                            myThread.Start();
                            Thread.Sleep(100);
                        }
                        if (sNode.InnerText == "trend")
                        {
                            myThread = new Thread(Trend1);
                            myThread.IsBackground = true;
                            myThread.Name = taskname;
                            myThread.Start();
                            Thread.Sleep(100);
                        }
                        if (sNode.InnerText == "script")
                        {
                            try
                            {
                                filename = ProjectPath + "tasks/" + taskname + ".js";
                                param = File.ReadAllText(filename);

                                myThread = new Thread(Script1);
                                myThread.Name = taskname;
                                myThread.Start();
                                Console.WriteLine(myThread.Name + " Started");
                                Thread.Sleep(100);
                            }
                            catch { }
                        }
                        if (sNode.InnerText == "io")
                        {
                            XmlElement? xmlRoot = taskFile.DocumentElement;
                            if (xmlRoot != null)
                            {
                                sNode = xmlRoot.SelectSingleNode("dll");


                                //Подтягиваем dll драйвера
                                string iodllpath = AppDomain.CurrentDomain.BaseDirectory + "/IO/" + sNode.InnerText + ".dll";
                                assmbl = Assembly.LoadFile(iodllpath);

                                oio = assmbl.CreateInstance(sNode.InnerText + ".IO");
                                tio = assmbl.GetType(sNode.InnerText + ".IO");

                                myThread = new Thread(IO);
                                myThread.IsBackground = true;
                                myThread.Name = taskname;
                                myThread.Start();
                                Thread.Sleep(100);
                            }
                        }
                        
                    }
                }
            }

        }
        

        i++;
        TagBuffer.WriteTag(out err, "System_Startup", 1);
        while (true)
        {
            TagBuffer.WriteTag(out err, "System_Time", DateTime.Now.ToLongTimeString());
            TagBuffer.WriteTag(out err, "System_Hour", DateTime.Now.Hour);
            TagBuffer.WriteTag(out err, "System_Minute", DateTime.Now.Minute);
            TagBuffer.WriteTag(out err, "System_Second", DateTime.Now.Second);
            TagBuffer.WriteTag(out err, "System_Date", DateTime.Now.ToShortDateString());
            TagBuffer.WriteTag(out err, "System_Day", DateTime.Now.Day);
            TagBuffer.WriteTag(out err, "System_Month", DateTime.Now.Month);
            TagBuffer.WriteTag(out err, "System_Year", DateTime.Now.Year);
            Thread.Sleep(500);
        }
       

    }


    public void Buffer()
    {
        TagBuffer.Init(ProjectPath);
    }
    public void DStorage()
    {
        Storage.Init(errtag, param);
    }
    public void WebServer()
    { 
        WPublisher.Init(param);
    }
    public void MailClient()
    {
        eMailClient.Init(errtag, param);
    }
    public void SMSClient()
    {
        SMS.Init(errtag, param, paramtag4);
    }
    
    public void Telegram()
    {
        TLGbot.Init(errtag, param, func, paramtag1, paramtag2, paramtag3, paramtag4);
    }
   
    public void Timer1()
    {
        TaskTimer.Timer tmr = new TaskTimer.Timer();
        tmr.Init(compltag, exectag, errtag, taskFile);
    }
    public void Clock1()
    {
        TaskClock.Clock clk = new TaskClock.Clock();
        clk.Init(compltag, exectag, errtag, taskFile);
    }

    public void Script1()
    {
        TaskScript.Script scrpt = new TaskScript.Script();
        scrpt.Init(compltag, exectag, errtag, param);

    }

    public void Alarm1()
    {
        TaskAlarm.Alarm alarm = new TaskAlarm.Alarm();
        alarm.Init(compltag, exectag, errtag, taskFile);
    }
    public void Trend1()
    {
        TaskTrend.Trend trend= new TaskTrend.Trend();
        trend.Init(compltag, exectag, errtag, taskFile);
    }

    
    public void IO()
    {
        
        Object[] ioparams = new Object[4];
         ioparams[0] = compltag;
         ioparams[1] = exectag;
         ioparams[2] = errtag;
         ioparams[3] = taskFile;
         MethodInfo mio = tio.GetMethod("Init");
         mio.Invoke(oio, ioparams);

    }
}